﻿using Octokit;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GitControl
{
    class Program
    {
        static TcpClient sock = new TcpClient("127.0.0.1", 6028);
        static bool exit = false;
        static string GitPath;

        static void send(string msg)
        {
            BinaryWriter writer = new BinaryWriter(sock.GetStream());
            writer.Write(Encoding.Unicode.GetBytes(msg));
        }

        /*
         * args[1] = git bash path
         * args[2] = operation folder
         * args[3] = mode
         *           {
         *              auto                - let gitcontrol handle it
         *              custom              - take care of it yourself with git command
         *              
         * args[4] = command
         *           {
         *              init                - initalize the folder and create repo in github
         *              commit              - commit changes
         *              push                - push repo to github
         *              pull                - fetch changes from github and merge
         *              clone               - clone repo from github
         *           }
         * 
         * args[5] = username
         * args[6] = password
         * args[7] = appendix message1      - description of repo when args[4] is "init" or commit message when args[4] is "commit"
         * args[8] = appendix message2      - decide whether the repo is private or not when args[4] is "init"
         */
        static async Task Main(string[] args)
        {
            //connect github
            GitHubClient client = new GitHubClient(new ProductHeaderValue("gitcontrol"));
            User user = null;
            try
            {
                while (!exit)
                {
                    byte[] data = new byte[1024];
                    int length = sock.GetStream().Read(data, 0, data.Length);
                    string ret = Encoding.UTF8.GetString(data, 0, length);
                    string[] e = ret.Split(' ');
                    switch(e[0])
                    {
                        case "login":
                            client.Credentials = new Credentials(e[1], e[2]);
                            user = await client.User.Current();
                            send("username "+user.Name);
                            break;
                        case "init":
                            git("cd " + e[1] + "&&git init");
                            NewRepository repo = new NewRepository(GetFolder(e[1]));
                            repo.Description = e[2];
                            repo.Private = e[3] == "private" ? true : false;
                            send("init succeed");
                            break;
                        case "commit":
                            git("cd " + e[1] + "&&git add .&&git commit -m '" + e[2] + "'");
                            break;
                        case "push":       //git@github.com:octokit/octokit.net.git
                            git("cd " + e[1] + "&&git push git@github.com:" + client.User.ToString()+GetFolder(e[1])+".git");
                            break;
                        case "pull":
                            git("cd " + e[1] + "&&git pull git@github.com:" + client.User.ToString() + GetFolder(e[1]) + ".git");
                            break;
                        case "exit":
                            exit = true;
                            break;
                        case "getrepos":
                             
                    }



                }
            }
            catch(Exception err)
            {
                switch(err.Message)
                {
                    case "Bad credentials":
                        send("login faild");
                        break;
                }
            }

            
            //send("hello vb6");


            //connect drag-controls IDE




            //Process process = new Process();
            //string command = "";
            //string[] tem = args[2].Split('\\');
            //if(args[3]=="auto")
            //{
            //    switch (args[4])
            //    {
            //        case "init":
            //            command = "cd " + args[2] + "&&git init";
            //            NewRepository repo = new NewRepository(tem[tem.Length-1]);
            //            repo.Description = args[7];
            //            repo.Private = args[8] == "private" ? true : false;
            //            break;
            //        case "commit":
            //            command = "cd " + args[2] + "&&git add .&&git commit -m '" + args[7] + "'";
            //            break;
            //        case "push":
            //            command = "cd " + args[2] + "&&git push";
            //            break;
            //        case "pull":
            //            command = "cd " + args[2] + "&&git pull";
            //            break;
            //        case "clone":

            //            break;
            //    }
            //}
            //else
            //{
            //    command = args[4];
            //}
            //process.StartInfo = new ProcessStartInfo()
            //{
            //    FileName = args[1],
            //    UseShellExecute = false,
            //    RedirectStandardOutput = true,
            //    Arguments = command;
            //};

        }
        static string git(string command)
        {
            Process process = new Process();
            process.StartInfo = new ProcessStartInfo()
            {
                FileName = GitPath,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                Arguments = command
            };
            process.Start();
            process.WaitForExit();
            return process.StandardOutput.ReadToEnd();
        }
        
        static string GetFolder(string path)
        {
            string[] tem = path.Split('\\');
            return tem[tem.Length];
        }
        ~Program()
        {
            sock.Close();
        }
    }
}
